<?php

namespace pmvc\mvc\view;

use pmvc\mvc\ViewHandler;
use pmvc\mvc\Request;
use pmvc\mvc\Response;
use pmvc\mvc\view\PropertiesLookup;
use pmvc\mvc\security\SecurityUtil;
use pmvc\util\ClassUtil;
use pmvc\log\Log;

class SmartyViewHandler 
    implements ViewHandler {

    public $smartyBootstrapFile;
    public $compileDir;
    public $configDir;
    public $cacheDir;
    public $useCache;
    public $templateDir;
    public $hooks;
    public $hookFile;
    
    private $smarty;
    private $file;
    
    /**
     * Creates this shit
     */
	public function renderView(Request $request, Response $response, $viewName) {
		
		// bring in smarty
		if (isset($this->smartyBootstrapFile) && !ClassUtil::requireFile($this->smartyBootstrapFile, TRUE)) {
			Log::error("Unable to locate smarty bootstrap file: {0}", $this->compileDir);
		}
    	
		// create needed directories
		if (!file_exists($this->compileDir) 
			&& !mkdir($this->compileDir, 755, TRUE)) {
			Log::error("Unable to create compile dir: {0}", $this->compileDir);
		}
		if (!file_exists($this->configDir) 
			&& !mkdir($this->configDir, 755, TRUE)) {
			Log::error("Unable to create config dir: {0}", $this->configDir);
		}
		if (!file_exists($this->cacheDir) 
			&& !mkdir($this->cacheDir, 755, TRUE)) {
			Log::error("Unable to create cache dir: {0}", $this->cacheDir);
		}

        // create
        $this->smarty = new \Smarty();
        
        // configure
        $this->smarty->template_dir = $this->templateDir;
        $this->smarty->compile_dir  = $this->compileDir;
        $this->smarty->config_dir   = $this->configDir;
        $this->smarty->cache_dir    = $this->cacheDir;
        $this->smarty->caching	    = strtolower($this->useCache)=="true";
        $this->smarty->use_sub_dirs = TRUE;
        
        // set variables
        $vars = Array(
            "request"	    => $_REQUEST,
            "post"	        => $_POST,
            "get"	        => $_GET,
            "session"       => $_SESSION,
            "server"	    => $_SERVER,
        	"requestedUrl"	=> $request->getRequestedUrl(),
        	"contextUrl"	=> $request->getContextUrl(),
        	"baseUrl"		=> $request->getBaseUrl(),
        	"security"		=> Array(
        		"user" => SecurityUtil::getCurrentUser($request),
        		"isLoggedIn" => SecurityUtil::isLoggedIn($request)
        	)
        );
        $this->smarty->assign($vars);
        $this->smarty->register_object("Request", $request);
        
        $contextProperties = $request->getDispatcher()->getApplicationContext()->getObjectsOfType('pmvc\Properties');
        if (!empty($contextProperties)) {
        	$propertiesLookup = new PropertiesLookup();
        	$propertiesLookup->addAll($contextProperties);
        	$this->smarty->register_object('ContextPropertiesLookup', $propertiesLookup, Array());
        }

        // bring in the functions 
        ClassUtil::requireFile("/pmvc/mvc/view/smarty_functions.php");
        
        // bring in the hook file
        if (!empty($this->hookFile)) {
			ClassUtil::requireFile($this->hookFile);
        }
        
        // retgister functions
        $this->smarty->register_function(
        	"pmvc_formInput", "smarty_pmvc_formInput", false);
        $this->smarty->register_function(
        	"pmvc_formSelect", "smarty_pmvc_formSelect", false);
        $this->smarty->register_function(
        	"pmvc_formTextArea", "smarty_pmvc_formTextArea", false);
        $this->smarty->register_function(
        	"pmvc_formInputCheckbox", "smarty_pmvc_formInputCheckbox", false);
        $this->smarty->register_function(
        	"pmvc_formInputPassword", "smarty_pmvc_formInputPassowrd", false);
        $this->smarty->register_function(
        	"pmvc_displayFormGlobalErrors", "smarty_pmvc_displayFormGlobalErrors", false);
        $this->smarty->register_function(
        	"pmvc_displayFormFieldErrors", "smarty_pmvc_displayFormFieldErrors", false);
        $this->smarty->register_function(
        	"pmvc_niceDate", "smarty_pmvc_niceDate", false);
        $this->smarty->register_function(
        	"pmvc_getContextProperty", "smarty_pmvc_getContextProperty", false);

        // register blocks
        $this->smarty->register_block(
        	"pmvc_hasRoles", "smarty_pmvc_hasRoles", false);

		// let something hook
		if (!empty($this->hooks)) {
			foreach ($this->hooks as $hook) {
				$hook->hook($this->smarty, $request, $response);
			}
		}

		// legacy hooks
		if (function_exists("pmvc_smarty_hook")) {
			pmvc_smarty_hook($this->smarty, $request, $response);
		}
		
        // put the model into the template
        $this->smarty->assign($response->getModel()->getArrayCopy());
        
        // render the view
		$response->getStream()->write($this->smarty->fetch($viewName));
    }
}

?>